package com.manster.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.manster.entity.SysRole;
import com.manster.entity.SysRoleMenu;
import com.manster.entity.SysUserRole;
import com.manster.util.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author manster
 * @since 2022-03-13
 */
@RestController
@RequestMapping("/sys/role")
@Api(tags = "角色管理")
public class SysRoleController extends BaseController {

    @ApiOperation("获取角色列表")
    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/list")
    public R list(String name){
        Page<SysRole> pageData = roleService.page(getPage(),
                new QueryWrapper<SysRole>().like(StrUtil.isNotBlank(name), "name", name));
        return R.success().data(pageData);
    }

    @ApiOperation("获取角色信息")
    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        SysRole role = roleService.getById(id);
        //获取角色相关联的菜单
        List<SysRoleMenu> roleMenus = roleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
        //提取菜单id
        List<Long> menuIds = roleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        role.setMenuIds(menuIds);
        return R.success().data(role);
    }

    @ApiOperation("新增角色信息")
    @PreAuthorize("hasAuthority('sys:role:save')")
    @PostMapping("/save")
    public R save(@Validated @RequestBody SysRole sysRole){
        roleService.save(sysRole);
        return R.success().data(sysRole);
    }

    @ApiOperation("修改角色信息")
    @PreAuthorize("hasAuthority('sys:role:update')")
    @PostMapping("/update")
    public R update(@Validated @RequestBody SysRole sysRole){
        roleService.updateById(sysRole);
        //删除缓存
        userService.clearUserAuthorityInfoByRoleId(sysRole.getId());
        return R.success().data(sysRole);
    }

    @ApiOperation("删除角色信息")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @PostMapping("/delete/{id}")
    @Transactional
    public R delete(@PathVariable("id") Long id){
        roleService.removeById(id);
        //删除缓存
        userService.clearUserAuthorityInfoByRoleId(id);
        //删除中间表
        userRoleService.remove(new QueryWrapper<SysUserRole>().eq("role_id",id));
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id",id));
        return R.success();
    }

    @ApiOperation("批量删除角色信息")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @PostMapping("/deleteBatch")
    @Transactional
    public R deleteBatch(@RequestBody Long[] ids){
        roleService.removeByIds(Arrays.asList(ids));

        //删除缓存
        for (Long id : ids) {
            userService.clearUserAuthorityInfoByRoleId(id);
        }
        //删除中间表
        userRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id",ids));
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id",ids));
        return R.success();
    }

    @ApiOperation("为角色分配权限")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    @PostMapping("/perm/{roleId}")
    @Transactional
    public R perm(@PathVariable("roleId") Long roleId, @RequestBody Long[] menuIds){

        List<SysRoleMenu> sysRoleMenus = new ArrayList<>();

        Arrays.stream(menuIds).forEach(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);
            sysRoleMenus.add(roleMenu);
        });
        //先删除原来的所有菜单记录，然后保存新的记录
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id",roleId));
        roleMenuService.saveBatch(sysRoleMenus);

        //删除缓存
        userService.clearUserAuthorityInfoByRoleId(roleId);

        return R.success().data(menuIds);
    }

}
